package com.horay.springbootdemo.async.context.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Servlet异步控制器
 *
 * @author heyingcheng
 * @date 2019/9/1 23:58
 */
@Slf4j
@RestController
@RequestMapping("async/context")
public class ServletAsyncController {

    @GetMapping("servlet")
    public void servlet(HttpServletRequest request, HttpServletResponse response) {
        AsyncContext asyncContext = request.startAsync();
        // 设置监听器: 可设置其开始、完成、异常、超时等事件的回调处理
        asyncContext.addListener(new AsyncListener() {

            @Override
            public void onTimeout(AsyncEvent event) throws IOException {
                log.info("ServletAsyncController.servlet方法请求超时");
            }

            @Override
            public void onStartAsync(AsyncEvent event) throws IOException {
                log.info("ServletAsyncController.servlet方法线程开始");
            }

            @Override
            public void onError(AsyncEvent event) throws IOException {
                log.error("ServletAsyncController.servlet方法发生错误：" + event.getThrowable());
            }

            @Override
            public void onComplete(AsyncEvent event) throws IOException {
                log.info("ServletAsyncController.servlet方法执行完成");
                //  这里可以做一些清理资源的操作...
            }

        });

        // 设置超时时间
        asyncContext.setTimeout(20000);
        asyncContext.start(() -> {
            try {
                Thread.sleep(10000);
                log.info("内部线程：" + Thread.currentThread().getName());
                asyncContext.getResponse().setCharacterEncoding("utf-8");
                asyncContext.getResponse().setContentType("text/html;charset=UTF-8");
                asyncContext.getResponse().getWriter().println("ServletAsyncController.asyncContext.start方法异步的请求响应");
            } catch (Exception e) {
                log.error("ServletAsyncController.asyncContext.start方法异常：" + e);
            }
            // 异步请求完成通知
            // 此时整个请求才完成
            asyncContext.complete();
        });

        //此时之类 request的线程连接已经释放了
        log.info("ServletAsyncController.servlet方法主线程：" + Thread.currentThread().getName());
    }

}
